
function ajax(options) {

    const {
        type,
        url,
        data = {},
        dataType = 'json',
        async = true
    } = options;

    // 判断
    // 做参数的合法性判断
    if (type.toLowerCase() !== 'get' && type.toLowerCase() !== 'post') {
        throw new Error('请求方式不对');
    }

    // 判断路径   http / https 开头
    if (!url.startsWith('http') && !url.startsWith('https')) {
        throw new Error('请求路径不对');
    }

    if (typeof async !== 'boolean') {
        throw new Error('async只能是布尔值');
    }

    if (dataType.toLowerCase() !== 'json' && dataType.toLowerCase() !== 'string') {
        throw new Error('后端返回的数据类型必须是json或者string');
    }

    if (Object.prototype.toString.call(data) !== '[object Object]') {
        throw new Error('data必须是object');
    }



    // 把这个data变成字符串   {username:'yy' , password : 123}   username=yy&password=123

    let params = '';
    // 遍历对象
    for (let key in data) {
        params += `${key}=${data[key]}&`;
    }
    params = params.substring(0, params.length - 1);
    // console.log(params);



    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();

        // 区分  get / post
        if (type.toLowerCase() === 'get') {
            xhr.open(type, url + '?' + params, async);
            xhr.send();
        }
        else if (type.toLowerCase() === 'post') {
            xhr.open('post', url, true);

            // post请求需要携带请求头   
            xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');

            // post请求是通过send携带参数   key=value&key=value
            xhr.send(params);
        }

        xhr.onreadystatechange = function () {
            if (this.readyState === 4) {
                if (this.status === 200) {
                    let data = this.responseText;
                    // 判断JSON
                    if (dataType.toLowerCase() === 'json') {
                        data = JSON.parse(data);
                    }
                    resolve(data);
                }
                else {
                    reject(this.status)
                }

            }
        }

    })



}